﻿//
// Created by WJ on 2025/9/17.
//

#include "ModbusTcpClient.h"

#include <functional>
#include <libmodbus/modbus.h>
#include <iostream>
#include <thread>


ModbusTcpClient::ModbusTcpClient()
{
    const char* serverIp = "127.0.0.1";
    int serverPort = 502;

    // 使用 modbus_new_tcp() 创建一个 Modbus TCP 上下文
    ctx = modbus_new_tcp(serverIp, serverPort);

    if (ctx == nullptr)
    {
        std::cerr << "ctx创建失败, ip: " << serverIp << ", port: " << serverPort << std::endl;
    }
    else
    {
        std::cout << "ctx创建成功, ip: " << serverIp << ", port: " << serverPort << std::endl;
    }
}

ModbusTcpClient::~ModbusTcpClient()
{
    stopMonitor(risingEdgeTask);
    if (ctx != nullptr)
    {
        modbus_close(ctx);
        modbus_free(ctx);
        std::cout << "ctx已释放。" << std::endl;
    }
}

bool ModbusTcpClient::connect()
{
    if (ctx == nullptr)
    {
        std::cerr << "ctx未初始化，无法连接。" << std::endl;
        return false;
    }
    if (modbus_connect(ctx) == -1)
    {
        std::cerr << "连接失败：" << modbus_strerror(errno) << std::endl;
        return false;
    }
    std::cout << "成功连接到服务器。" << std::endl;
    return true;
}

void ModbusTcpClient::disconnect()
{
    stopMonitor(risingEdgeTask);
    if (ctx != nullptr)
    {
        modbus_close(ctx);
        std::cout << "已断开与服务器的连接。" << std::endl;
    }
}

void ModbusTcpClient::stopMonitor(MonitorTask& task)
{
    if (task.isMonitoring.load())
    {
        task.isMonitoring = false;
        if (task.monitorThread.joinable())
        {
            task.monitorThread.join();
        }
    }
}

bool ModbusTcpClient::read(int addr, int nb, uint16_t* dest)
{
    if (ctx == nullptr)
    {
        std::cerr << "ctx未初始化。" << std::endl;
        return false;
    }
    int ret = modbus_read_registers(ctx, addr, nb, dest);
    if (ret == -1)
    {
        std::cerr << "读取失败: " << modbus_strerror(errno) << std::endl;
        return false;
    }

    std::cout << "成功读取了 " << ret << " 个寄存器, 值为: " << *dest << std::endl;
    return true;
}


bool ModbusTcpClient::write(int reg_addr, const uint16_t value)
{
    if (ctx == nullptr)
    {
        std::cerr << "ctx未初始化。" << std::endl;
        return false;
    }

    int ret = modbus_write_register(ctx, reg_addr, value);
    if (ret == -1)
    {
        std::cerr << "写入单个寄存器失败: " << modbus_strerror(errno) << std::endl;
        return false;
    }

    std::cout << "成功向寄存器地址 " << reg_addr << " 写入了值 " << value << std::endl;
    return true;
}

bool ModbusTcpClient::write(int addr, int nb, const uint16_t* data)
{
    if (ctx == nullptr)
    {
        std::cerr << "ctx未初始化。" << std::endl;
        return false;
    }

    int ret = modbus_write_registers(ctx, addr, nb, data);
    if (ret == -1)
    {
        std::cerr << "写入多个寄存器失败: " << modbus_strerror(errno) << std::endl;
        return false;
    }

    std::cout << "成功向起始地址 " << addr << " 写入了 " << ret << " 个寄存器。" << std::endl;
    return true;
}
